import traceback
from typing import Generic, Protocol, TypeVar

from fastapi import Request, Response
from fastapi.exceptions import RequestValidationError
from starlette.datastructures import MutableHeaders
from starlette.exceptions import HTTPException
from starlette.responses import JSONResponse
from starlette.status import (
    HTTP_422_UNPROCESSABLE_ENTITY,
    HTTP_500_INTERNAL_SERVER_ERROR,
)

from app.core.handlers.loggers import logger
from app.core.handlers.response import FailResponse

T = TypeVar("T", bound=Exception)


class ExceptionHandlerCallable(Protocol):
    """异常处理器协议"""

    async def __call__(self, *args, **kwargs) -> Response: ...


class ExceptionHandlerBase(ExceptionHandlerCallable, Generic[T]):
    """
    异常处理器基类

    提供异常处理的通用实现，包括日志记录、响应构建等通用功能。
    子类需要实现 handle_exception 方法来处理特定类型的异常。

    """

    code: int = HTTP_500_INTERNAL_SERVER_ERROR
    headers: MutableHeaders = MutableHeaders()
    message: str = "服务器内部错误"

    async def __call__(self, request: Request, exc: T) -> JSONResponse:
        """
        异常处理入口方法

        Args:
            request (Request): HTTP请求对象
            exc (T): 捕获的异常对象

        Returns:
            JSONResponse: 格式化的错误响应
        """
        # 处理异常信息，由子类实现具体逻辑
        self.handle_exception(request, exc)

        # 记录异常堆栈信息
        logger.error(traceback.format_exc())

        # 添加请求ID到响应头
        # self.headers["X-Request-ID"] = request.state.request_id

        # 构建失败响应
        response = FailResponse(code=self.code, message=self.message)
        content = response.model_dump()

        # 记录响应日志
        logger.info(f"API Response Sent, response={content}, {exc=}")

        # 返回JSON格式的错误响应
        return JSONResponse(
            content=content,
            status_code=self.code,
            headers=self.headers,
        )

    def handle_exception(self, request: Request, exc: T):
        """
        处理异常信息

        该方法需要被子类重写以处理特定类型的异常。

        Args:
            request (Request): HTTP请求对象
            exc (T): 异常对象

        Raises:
            NotImplementedError: 基类方法未被实现
        """
        raise NotImplementedError


class HTTPExceptionHandler(ExceptionHandlerBase[HTTPException]):
    """HTTP异常处理器"""

    def handle_exception(self, request: Request, exc: HTTPException):
        self.code = exc.status_code
        self.message = exc.detail
        self.headers = MutableHeaders(exc.headers)


class RequestValidationErrorHandler(ExceptionHandlerBase[RequestValidationError]):
    """请求验证错误处理器"""

    def handle_exception(self, request: Request, exc: RequestValidationError):
        message = []
        # 遍历所有验证错误并格式化
        for error in exc.errors():
            path = ".".join(error["loc"])
            msg = error["msg"]
            value = error["input"]
            message.append(f"Parameter {path} is invalid, {msg}, {value=}")

        self.code = HTTP_422_UNPROCESSABLE_ENTITY
        self.message = "\n".join(message)


class ExceptionHandler(ExceptionHandlerBase):
    """通用异常处理器"""

    code = HTTP_500_INTERNAL_SERVER_ERROR

    def handle_exception(self, request: Request, exc: Exception):
        self.message = str(exc)


custom_exception_handlers: dict[int | type[Exception], ExceptionHandlerCallable] = {
    HTTPException: HTTPExceptionHandler(),
    RequestValidationError: RequestValidationErrorHandler(),
    Exception: ExceptionHandler(),
}
